home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1985-1992 New York University
- *
- * This file is part of the Ada/Ed-C system. See the Ada/Ed README file for
- * warranty (none) and distribution info and also the GNU General Public
- * License for more details.
-
- */
- /* misc.c - miscellaneous programs */
-
- #ifdef PALLOC
- #define calloc pcalloc
- #define free pfree
- #define cfree pcfree
- #define malloc pmalloc
- #define realloc prealloc
- #endif
-
- #include "config.h"
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include "time.h"
- #include "ifile.h"
- #include "miscprots.h"
-
- #ifndef LIBDIR
- #define LIBDIR "/usr/local/lib"
- #endif
-
- #ifdef vms
- #include <file.h>
- #include descrip
- #endif
-
- #ifdef ADALIB
- #ifdef vms
- /*
- #include "adalib.h"
- */
- #endif
- #define EXIT_INTERNAL_ERROR
- #endif
-
- #ifdef BINDER
- #ifdef vms
- /*
- #include "adabind.h"
- */
- #endif
- #define EXIT_INTERNAL_ERROR
- extern int adacomp_option;
- #endif
-
- #ifdef INT
- #ifdef vms
- /*
- #include "adaexec.h"
- */
- #endif
- #define EXIT_INTERNAL_ERROR
- #endif
-
- #ifndef EXPORT
- #undef EXIT_INTERNAL_ERROR
- #endif
- #ifdef BSD
- #include <sys/file.h>
- #endif
-
- #ifdef vms
- char *DIRECTORY_START = "[."; /* used as the beginning of a VMS dir spec. */
- #endif
-
- char *LIBRARY_PREFIX= "";
-
- /* PREDEFNAME gives directory path to predef files.
- * libset() is used to toggle between libraries (the users and predef).
- * tname = libset(lname) sets library prefix for ifopen, etc. to lname
- * and returns prior setting in tname.
- */
-
- static void openerr(char *filename, char *mode);
- static void fhlist(IFILE *, char *);
-
- #ifdef DEBUG
- #define IOT
- int malloctrace = 0;
- void trace_malloc() /*;trace_malloc*/
- {
- malloctrace = 1;
- }
- #endif
-
- static int ifiles = 0;
-
- #ifdef SMALLOC
- unsigned int smalloc_free = 0;
- char *smalloc_ptr;
- #define SMALLOC_BLOCK 2000
- char **smalloc_table = (char **)0;
- unsigned smalloc_blocks = 0;
- #endif
-
- char *smalloc(unsigned n) /*;smalloc*/
- {
- /* variant of malloc for use for blocks that will never be freed,
- * primarily blocks used for small strings. This permits allocation
- * in larger blocks avoiding the malloc overhead required for each block.
- */
- #ifndef SMALLOC
- return emalloct(n, "smalloc");
- #else
- char *p;
- if (n & 1) n+= 1;
- #ifdef ALIGN4
- if (n & 2) n+= 2;
- #endif
-
- if (n > SMALLOC_BLOCK) { /* large block allocated separately */
- #ifdef DEBUG
- printf("smalloc: warning block %u exceeds %d SMALLOC_BLOCK\n",
- n, SMALLOC_BLOCK);
- #endif
- p = emalloct(n, "smalloc");
- return p;
- }
- if (n > smalloc_free) {
- smalloc_ptr = emalloct(SMALLOC_BLOCK, "smalloc-block");
- smalloc_free = SMALLOC_BLOCK;
- smalloc_blocks++;
- if (smalloc_blocks == 1) {
- smalloc_table = (char **) emalloct(sizeof (char **),
- "smalloc-table");
- }
- else { /* reallocate blocks */
- smalloc_table = (char **) erealloct((char *)smalloc_table,
- sizeof(char **) * (smalloc_blocks), "smalloc-table-realloc");
- }
- smalloc_table[smalloc_blocks-1] = smalloc_ptr;
- }
- p = smalloc_ptr;
- smalloc_ptr += n;
- smalloc_free -= n;
- return p;
- #endif
- }
-
- #ifdef DEBUG
- void smalloc_list()
- {
- int i;
- char **st;
- st = smalloc_table;
- for (i = 0; i < smalloc_blocks; i++) {
- printf("%d %ld %x\n", i, *st, *st);
- st++;
- }
- }
- #endif
-
- int is_smalloc_block(char *p) /*;is_smalloc_block*/
- {
- /* returns TRUE is p points within block allocated by smalloc */
- #ifdef SMALLOC
- #ifdef IBM_PC
- /* for PC need to do 32 bit pointer comparisons */
- /*
- pragma off(segmented_pointer_operations);
- */
- #endif
- int i;
- char **st;
-
- st = smalloc_table;
- if (smalloc_blocks == 0) chaos("is_malloc_block - no blocks");
- for (i = 0; i < smalloc_blocks; i++) {
- if (*st <= p && p < (*st+(SMALLOC_BLOCK-1)))
- return TRUE;
- st++;
- }
- return FALSE;
- #ifdef IBM_PC
- /*
- pragma on(segmented_pointer_operations);
- */
- #endif
- #else
- return FALSE;
- #endif
- }
-
- void capacity(char *s) /*;capacity*/
- {
- /* called when compiler capacity limit exceeded.
- * EXIT_INTERNAL_ERROR is defined when the module is run by itself
- * (not spawned from adacomp) and DEBUG is not defined.
- */
- #ifdef EXIT_INTERNAL_ERROR
- #ifdef vms
- LIB$STOP(MSG_CAPACITY);
- #else
- fprintf(stderr, "capacity limit exceeded: %s\n", s);
- exitp(RC_INTERNAL_ERROR);
- #endif
- #else
- #ifdef DEBUG
- printf("capacity limit exceeded: %s\nexecution abandoned \n", s);
- #endif
- fprintf(stderr, "capacity limit exceeded: %s\n", s);
- exitp(RC_INTERNAL_ERROR);
- #endif
- }
-
- #ifdef CHAOS
- void chaos(char *s) /*;chaos*/
- {
- /* called when internal logic error detected and it is not meaningful
- * to continue execution. This is never defined for the export version.
- */
- fprintf(stderr, "chaos: %s\nexecution abandoned \n", s);
- printf("chaos: %s\nexecution abandoned \n", s);
- exitp(RC_INTERNAL_ERROR);
- }
- #else
- void exit_internal_error() /*;exit_internal_error*/
- {
- /* called when internal logic error detected and it is not meaningful
- * to continue execution. This procedure is called by the export version.
- * EXIT_INTERNAL_ERROR is defined when the module is run by itself
- * (not spawned from adacomp) and EXPORT is defined.
- * Now that adabind is a separate module which can be called by itself
- * or spawned from adacomp, we must test the run time flag adacomp_option
- * to determine which case it is.
- */
- #ifdef EXIT_INTERNAL_ERROR
- #ifdef vms
- LIB$STOP(MSG_CHAOS);
- #else
- #ifdef BINDER
- if (adacomp_option)
- #endif
- fprintf(stderr, "Adaed internal error - Please report.\n");
- exit(RC_INTERNAL_ERROR);
- #endif
- #else
- exit(RC_INTERNAL_ERROR);
- #endif
- }
- #endif
-
- void exitp(int n) /*;exitp*/
- {
- /* synonym for exit() used so can trap exit() calls with debugger */
- exit(n);
- }
-
- char *ecalloc(unsigned nelem, unsigned nsize) /*;ecalloc */
- {
- /* calloc with error check if no more */
-
- char *p;
-
- if (nelem > 20000) chaos("ecalloc: ridiculous argument");
-
- p = calloc (nelem, nsize);
- if (p == (char *) 0)
- capacity("out of memory \n");
- return p;
- }
-
- char *emalloc(unsigned n) /*;emalloc */
- { /* avoid BUGS - use calloc which presets result to zero ds 3 dec 84*/
- /* malloc with error check if no more */
-
- char *p;
-
- if (n > 50000) chaos("emalloc: ridiculous argument");
- p = calloc (1, n);
- if (p == (char *) 0)
- capacity("out of memory \n");
- return (p);
- }
-
- char *erealloc(char *ptr, unsigned size) /*;eralloc */
- {
- /* realloc with error check if no more */
-
- char *p;
-
- p = realloc (ptr, size);
- if (p == (char *) 0)
- capacity("erealloc: out of memory \n");
- return (p);
- }
-
- char *strjoin(char *s1, char *s2) /*;strjoin */
- {
- /* return string obtained by concatenating argument strings
- * watch for either argument being (char *)0 and treat this as null string
- */
-
- char *s;
-
- if (s1 == (char *)0) s1= "";
- if (s2 == (char *)0) s2 = "";
- s = smalloc((unsigned) strlen(s1) + strlen(s2) + 1);
- strcpy(s, s1);
- strcat(s, s2);
- return s;
- }
-
- int streq(char *a, char *b) /*;streq*/
- {
- /* test two strings for equality, allowing for null pointers */
- if (a == (char *)0 && b == (char *)0)
- return TRUE;
- else if (a == (char *)0 || b == (char *)0)
- return FALSE;
- else return (strcmp(a, b) == 0);
- }
-
- char *substr(char *s, int i, int j) /*;substr */
- {
- /* return substring s(i..j) if defined, else return null ptr*/
-
- int n;
- char *ts, *t;
-
- if (s == (char *)0) return (char *) 0;
- n = strlen(s);
- if (!(i > 0 && j <= n && i <= j)) return (char *)0;
- /* allocate result, including null byte at end */
- ts = smalloc((unsigned) j - i + 2);
- t = ts;
- s = s + (i - 1); /* point to start of source*/
- for (; i <= j; i++) *t++ = *s++; /* copy characters */
- *t = '\0'; /* terminate result */
- return ts;
- }
-
- /* getopt(3) procedure obtained from usenet */
- /*
- * getopt - get option letter from argv
- */
- #ifdef IBM_PC
- #define nogetopt
- #endif
-
- #ifdef nogetopt
- char *optarg; /* Global argument pointer. */
- int optind = 0; /* Global argv index. */
-
- static char *scan = NULL; /* Private scan pointer. */
-
- int getopt(int argc, char **argv, char *optstring) /*;getopt */
- {
- register char c;
- register char *place;
- optarg = NULL;
-
- if (scan == NULL || *scan == '\0') {
- if (optind == 0)
- optind++;
-
- if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
- return (EOF);
- if (strcmp (argv[optind], "--") == 0) {
- optind++;
- return (EOF);
- }
-
- scan = argv[optind] + 1;
- optind++;
- }
-
- c = *scan++;
- place = strchr (optstring, c);
-
- if (place == NULL || c == ':') {
- fprintf (stderr, "%s: unknown option -%c\n", argv[0], c);
- return ('?');
- }
-
- place++;
- if (*place == ':') {
- if (*scan != '\0') {
- optarg = scan;
- scan = NULL;
- }
- else {
- optarg = argv[optind];
- optind++;
- }
- }
- return (c);
- }
- #endif
-
- char *greentime(int un) /*;greentime*/
- {
- /* get greenwich time in string of 23 characters.
- * format of result is as follows
- * 1984 10 02 16 30 36 nnn
- * 123456789a123456789b123
- * year mo da hr mi se uni
- *
- * greenwich time is used to avoid problems with daylight savings time.
- * The last three characters are the compilation unit number
- * (left filled with zeros if necessary).
- * NOTE: changed to use local time to give approx. same time as
- * SETL version ds 20 nov 84
- */
-
- char *s;
- #ifndef IBM_PC
- long clock;
- #else
- /* IBM_PC (Metaware) */
- time_t clock;
- #endif
- /*struct tm *gmtime();*/
- struct tm *t;
- #ifndef IBM_PC
- clock = time(0);
- #else
- time(&clock);
- #endif
- s = smalloc(24);
- /*t = gmtime(&clock);*/
- t = localtime(&clock);
- sprintf(s,"%04d %02d %02d %02d %02d %02d %03d",
- #ifdef IBM_PC
- /* needed until Metaware fixes bug in tm_year field (ds 6-19-86) */
- t->tm_year , t->tm_mon + 1, t->tm_mday,
- #else
- t->tm_year + 1900, t->tm_mon + 1, t->tm_mday,
- #endif
- t->tm_hour, t->tm_min, t->tm_sec, un);
- return s;
- }
-
- FILE *efopenl(char *filename, char *suffix, char *type, char *mode) /*;efopenl*/
- {
- char *fname;
- FILE *f;
-
- fname = ifname(filename, suffix);
- f = efopen(fname, type, mode);
- efree(fname);
- return f;
- }
-
- FILE *efopen(char *filename, char *type, char *mode) /*;efopen*/
- {
- FILE *f;
- #ifdef IBM_PC
- char *p;
- /* mode only meaningful for IBM PC for now */
-
- p = emalloc((unsigned) (strlen(type) + strlen(mode) + 1));
- strcpy(p, type);
- strcat(p, mode);
- f = fopen(filename, p);
- efree(p);
- #else
- f = fopen(filename, type);
- #endif
- if (f == (FILE *)0)
- openerr(filename, type);
- return f;
- }
-
- void efree(char *p) /*;efree*/
- {
- /* free with check that not tryig to free null pointer*/
- if (p == (char *)0)
- chaos("efree: trying to free null pointer");
- free(p);
- }
-
- int strhash(char *s) /*;strhash*/
- {
- /* Hashing function from strings to numbers */
-
- register int hash = 0;
-
- /* add character values together, adding in the cumulative hash code
- * at each step so that 'ABC' and 'BCA' have different hash codes.
- */
- while (*s)
- hash += hash + *s++;
- if (hash < 0) hash = - hash; /* to avoid negative hash code */
- return hash;
- }
-
- char *unit_name_type(char *u) /*;unit_name_type*/
- {
- int n;
- char *s;
-
- n = strlen(u);
- if (n < 2) {
- s = smalloc(1);
- *s = '\0';
- return s;
- }
- /* otherwise, return first two characters */
- s = smalloc(3);
- s[0] = u[0];
- s[1] = u[1];
- s[2] = '\0';
- return s;
- }
-
- #ifdef BSD
- /* BSD doesn't support strchr() and strrchr(), but they are just
- * named index() and rindex(), respectively, so here is code for BSD
- */
- char *strchr(char *s, int c)
- {
- return index(s, (char) c);
- }
-
- char *strrchr(char *s, int c)
- {
- return rindex(s, (char) c);
- }
- #endif
-
- char *libset(char *lname) /*;libset*/
- {
- char *old_name;
-
- old_name = LIBRARY_PREFIX;
- LIBRARY_PREFIX = lname;
- return old_name;
- }
-
- char *ifname(char *filename, char *suffix) /*;ifname*/
- {
- char *fname;
-
- /* allow room for library prefix, file name and suffix */
- #ifdef vms
- if (strchr(LIBRARY_PREFIX, '[')) {
- fname = emalloc((unsigned) (strlen(LIBRARY_PREFIX) +
- strlen(filename) + strlen(suffix) + 2));
- }
- else {
- fname = emalloc((unsigned) (strlen(LIBRARY_PREFIX) +
- strlen(filename) + strlen(suffix) + 3 + 2));
- }
- #else
- fname = emalloc((unsigned) (strlen(LIBRARY_PREFIX) + strlen(filename) +
- strlen(suffix) + 3));
- #endif
- if (strlen(LIBRARY_PREFIX)) { /* prepend library prefix if present */
- #ifdef vms
- if (strchr(LIBRARY_PREFIX, '[')) {
- strcpy(fname, LIBRARY_PREFIX);
- }
- else {
- strcpy(fname, DIRECTORY_START);
- strcat(fname, LIBRARY_PREFIX);
- }
- #else
- strcpy(fname, LIBRARY_PREFIX);
- #endif
- #ifdef IBM_PC
- strcat(fname, "\\");
- #endif
- #ifdef BSD
- strcat(fname, "/");
- #endif
- #ifdef SYSTEM_V
- strcat(fname, "/");
- #endif
- #ifdef vms
- if (!strchr(LIBRARY_PREFIX, '['))
- strcat(fname, "]");
- #endif
- strcat(fname, filename);
- }
- else {
- strcpy(fname, filename); /* copy name if no prefix */
- }
- if (strlen(suffix)) {
- strcat(fname, ".");
- strcat(fname, suffix);
- }
- return fname;
- }
-
- IFILE *ifopen(char *filename, char *suffix, char *mode, char *typea,
- int trace, int pass) /*;ifopen*/
- {
- #ifdef HI_LEVEL_IO
- FILE *file;
- #else
- int file;
- int flag;
- #endif
- char ftype, fversion, version;
- char type, modec;
- char *fname;
- long s = 0L;
- int nr, opened = FALSE, error = FALSE;
- IFILE *ifile;
- #ifdef IBM_PC
- char *t_name;
- #endif
-
- type = typea[0];
- modec= mode[0];
- #ifdef IOT
- if (trace) {
- printf("%s ", filename);
- }
- #endif
-
- fname = ifname(filename, suffix); /* expand file name */
-
- #ifdef IBM_PC
- /* mode only meaningful for IBM PC for now */
- t_name = emalloc((unsigned) (strlen(mode) + 2));
- strcpy(t_name, mode);
- strcat(t_name, "b");
- file = fopen(fname, t_name);
- efree(t_name);
- #else
- #ifdef HI_LEVEL_IO
- file = fopen(fname, mode);
- #else
- #ifdef vms
- if (modec == 'w') {
- while(~delete(strjoin(fname, ";")));
- }
- #endif
- if (mode[0] == 'w' || mode[1] == '+') {
- flag = O_CREAT | O_RDWR;
- }
- else {
- /* ASSUMING only other possibility is "r" !! */
- flag = O_RDONLY;
- }
- file = open(fname, flag, 0700);
- #endif
- #endif
-
- #ifdef HI_LEVEL_IO
- if (file == (FILE *)0) {
- #else
- if (file == -1) {
- #endif
- if (pass)
- return (IFILE *) 0;
- else
- openerr(fname, mode);
- }
- ifile = (IFILE *) emalloc(sizeof(IFILE));
- version = (type == 'a') ? AIS_VERSION : (type == 't') ? TRE_VERSION :
- (type == 'l') ? LIB_VERSION : (type == 's') ? STUB_VERSION :
- (type == 'p') ? AST_VERSION : '?';
- ifiles++;
- if (modec == 'w') { /* write header */
- /* write long at start to later be replaced with slots offset */
- ifile->fh_mode = modec;
- ifile->fh_type = type;
- ifile->fh_version = version;
- ifile->fh_slots = 0;
- ifile->fh_units_end = 0;
- #ifdef HI_LEVEL_IO
- /* will be upated on close */
- fwrite((char *) ifile, sizeof(IFILE), 1, file);
- #else
- write(file, (char *)ifile, sizeof(IFILE));
- #endif
- }
- else if (modec == 'r') { /* read and check header */
- #ifdef HI_LEVEL_IO
- nr = fread((char *) ifile, sizeof(IFILE), 1, file);
- #else
- nr = read(file, (char *) ifile, sizeof(IFILE));
- #endif
-
- #ifdef HI_LEVEL_IO
- if (nr != 1) {
- #else
- if (nr != sizeof(IFILE)) {
- #endif
- #ifdef DEBUG
- printf("ifopen - unable to read header\n");
- #endif
- error = TRUE;
- }
- ftype = ifile->fh_type;
- if (!error && ftype != type) {
- #ifdef DEBUG
- printf("ifopen read wrong type\n");
- #endif
- error = TRUE;
- }
- fversion = ifile->fh_version;
- if (!error && fversion != version) {
- #ifdef DEBUG
- printf("open file read wrong version\n");
- #endif
- error = TRUE;
- }
- }
- if (error) {
- openerr(fname, mode);
- }
- ifile->fh_number = ifiles;/* set count so can match open and close*/
- ifile->fh_trace = trace;
- ifile->fh_file = file;
- ifile->fh_mode = modec;
-
- #ifdef DEBUG
- if (ifile->fh_trace) fhlist(ifile, "open");
- #endif
- efree(fname);
- return ifile;
- }
-
- static void openerr(char *filename, char *mode) /*;openerr*/
- {
- /* EXIT_INTERNAL_ERROR is defined when the module is run by itself
- * (not spawned from adacomp) and DEBUG is not defined.
- */
- #ifdef EXIT_INTERNAL_ERROR
- #ifdef vms
- struct dsc$descriptor_s file_name;
- file_name.dsc$w_length = strlen(filename);
- file_name.dsc$b_dtype = DSC$K_DTYPE_T;
- file_name.dsc$b_class = DSC$K_CLASS_S;
- file_name.dsc$a_pointer = filename;
- LIB$SIGNAL(MSG_NOTOPEN, 1, &file_name);
- exit();
- #else
- fprintf(stderr, "Unable to open file %s for %s \n", filename,
- (strcmp(mode, "w") == 0 ? "writing"
- : (strcmp(mode, "r") == 0 ? "reading"
- : (strcmp(mode, "a") == 0 ? "appending"
- : mode))));
- exit(RC_ABORT);
- #endif
- #else
- fprintf(stderr, "Unable to open file %s for %s \n", filename,
- (strcmp(mode, "w") == 0 ? "writing"
- : (strcmp(mode, "r") == 0 ? "reading"
- : (strcmp(mode, "a") == 0 ? "appending"
- : mode))));
- exit(RC_ABORT);
- #endif
- }
-
- void ifclose(IFILE *ifile) /*;ifclose*/
- {
- #ifdef HI_LEVEL_IO
- FILE *file;
- #else
- int file;
- #endif
-
- #ifdef DEBUG
- if (ifile->fh_trace) fhlist(ifile, "close");
- #endif
-
- file = ifile->fh_file;
- /* write out file header if write mode */
- if (ifile->fh_mode == 'w') {
- ifile->fh_trace = 0; /* trace and number fields internal use only */
- ifile->fh_number = 0;
- ifile->fh_mode = '\0';
- ifseek(ifile, "update-header", 0L, 0);
- #ifdef HI_LEVEL_IO
- fwrite((char *)ifile, sizeof(IFILE), 1, file);
- #else
- write(file, (char *)ifile, sizeof(IFILE));
- #endif
- }
- #ifdef HI_LEVEL_IO
- if (file == (FILE *)0)
- chaos("ifclose: closing unopened file");
- fclose(file);
- ifile->fh_file = (FILE *)0;
- #else
- if (file== -1)
- chaos("ifclose: closing unopened file");
- close(file);
- ifile->fh_file = 0;
- #endif
- }
-
- void ifoclose(IFILE *ifile) /*;ifoclose*/
- {
- /* close file if still open */
- #ifdef HI_LEVEL_IO
- if (ifile != (IFILE *) 0 && ifile->fh_file != (FILE *) 0) {
- #else
- if (ifile != (IFILE *) 0 && ifile->fh_file != 0) {
- #endif
- ifclose(ifile);
- }
- }
-
- #ifdef DEBUG
- static void fhlist(IFILE *ifile, char *desc) /*;fhlist*/
- {
- /* list file header if tracing */
- printf("%s %c %d%c version %c trace %d", desc, ifile->fh_mode,
- ifile->fh_number, ifile->fh_type, ifile->fh_version, ifile->fh_trace);
- printf(" slots %ld units_end %ld\n", ifile->fh_slots, ifile->fh_units_end);
- }
- #endif
-
- long ifseek(IFILE *ifile, char *desc, long offset, int ptr) /*;ifseek*/
- {
- long begpos, endpos, seekval;
- begpos = iftell(ifile);
- #ifdef HI_LEVEL_IO
- seekval = fseek(ifile->fh_file, offset, ptr);
- #else
- seekval = lseek(ifile->fh_file, offset, ptr);
- #endif
- if (seekval == -1) chaos("ifseek: improper seek");
-
- endpos = iftell(ifile);
- #ifdef IOT
- if (ifile->fh_trace > 1 )
- printf("%s seek %d%c from %ld to %ld\n", desc,
- ifile->fh_number, ifile->fh_type, begpos, endpos);
- #endif
- return endpos;
- }
-
- long iftell(IFILE *ifile) /*;iftell*/
- {
- /* ftell, but arg is IFILE */
- #ifdef HI_LEVEL_IO
- return ftell(ifile->fh_file);
- #else
- return lseek(ifile->fh_file, 0, 1);
- #endif
- }
-
- /* define MEAS_ALLOC to measure alloc performance */
- #define MEAS_ALLOC
- /* this causes each malloc action to write a line to standard output
- * formatted as follows:
- * code:one of a, r, f
- * a allocate block
- * r reallocate block
- * f free block
- * the block address (integer)
- * the block length (or zero if not applicable)
- * the remainder of the line describes the action
- */
-
- extern FILE *MALFILE;
-
- #ifndef EXPORT
- char *emalloct(unsigned n, char *s) /*;emalloct*/
- {
- char *p;
- p = emalloc(n);
- #ifdef DEBUG
- if (malloctrace) fprintf(MALFILE, "a %ld %u %s\n", p, n, s);
- #endif
- return p;
- }
- #endif
-
- #ifndef EXPORT
- char *malloct(unsigned n, char *s) /*;malloct*/
- {
- /* like emalloct, but ok if not able to allocate block */
- char *p;
- p = malloc(n);
- #ifdef DEBUG
- if (p != (char *)0 && malloctrace)
- fprintf(MALFILE, "a %ld %u %s\n", p, n, s);
- #endif
- return p;
- }
- #endif
-
- #ifndef EXPORT
- char *ecalloct(unsigned n, unsigned m, char *msg)
- {
- char *p;
- p = ecalloc(n, m);
- #ifdef DEBUG
- if (malloctrace) fprintf(MALFILE, "a %ld %u %s\n", p, n*m, msg);
- #endif
- return p;
- }
- #endif
-
- #ifndef EXPORT
- char *erealloct(char *ptr, unsigned size, char *msg) /*;erealloct*/
- {
- char *p;
- p = erealloc(ptr, size);
- #ifdef DEBUG
- if (p == ptr) return p;
- if (malloctrace) /* trace line includes old address before msg */
- fprintf(MALFILE, "r %ld %u %ld %s\n", p, size, ptr, msg);
- #endif
- return p;
- }
- #endif
-
- #ifndef EXPORT
- void efreet(char *p, char *msg) /*;efreet*/
- {
- #ifdef DEBUG
- if (malloctrace) fprintf(MALFILE, "f %ld 0 %s\n", p, msg);
- #endif
- efree(p);
- }
- #endif
-
- char *predef_env() /*;predef_env*/
- {
- #ifndef IBM_PC
- char *s = getenv("ADAEDPREDEF");
- if (s == (char *)0) s = get_libdir();
- return s;
- #else
- char *getenv();
- return getenv("ADAED");
- #endif
- }
-
- char *get_libdir()
- {
- char *s = getenv("ADAED");
- if (s == (char *)0)
- return LIBDIR;
- else
- return s;
- }
-
- char *parsefile(char *s, int *np, int *nb, int *ns) /*;parsefile*/
- {
- /* Parse file name s, returning the length of prefix, base part, and
- * suffix in np, nb, and nl, respectively. A pointer to the start of
- * the base part is returned, or the null pointer if no base part.
- * The suffix is assumed to begin with period.
- * The prefix ends with the last instance of any of the prefix characters.
- */
-
- #ifdef IBM_PC
- char *prefix_chars = ":/\\";
- #endif
- #ifdef BSD
- char *prefix_chars = "/";
- #endif
- #ifdef SYSTEM_V
- char *prefix_chars = "/";
- #endif
- #ifdef vms
- char *prefix_chars = ":[]";
- #endif
- int n,i;
- char *pb;
- char *p, *p2;
- char *suffix_chars = ".";
- int have_prefix = 0;
-
- n = strlen(s);
- pb = s; /* assume name starts with base */
- *ns = 0;
- p = s + n; /* point to last (null) character in s */
- /* find length of suffix */
- /* but if find a prefix character first, then no suffix possible */
- for (i = n - 1; i >= 0; i--) {
- p--;
- for (p2 = prefix_chars; *p2 !='\0';) {
- if (*p == *p2++) {
- /* (p-s) gives number of characters before suffix */
- have_prefix = 1;
- break;
- }
- }
- if (!have_prefix) {
- for (p2 = suffix_chars; *p2 !='\0';) {
- if (*p == *p2++) {
- /* (p-s) gives number of characters before suffix */
- *ns = n - (p - s);
- break;
- }
- }
- }
- }
- /* find length of prefix */
- *np = 0;
- p = s + n;
- for (i = n - 1; i >= 0; i--) {
- p--;
- for (p2 = prefix_chars; *p2 !='\0';) {
- if (*p == *p2++) {
- p++; /* include last delimiter in prefix */
- /* (p-s) now gives prefix length*/
- *np = (p - s);
- pb = p;
- break;
- }
- }
- }
- /* base is what remains after removing prefix and suffix*/
- *nb = n - (*np + *ns);
- if (*nb == 0)
- pb = (char *)0; /* if no base */
- return pb;
- }
-